package com.coincalf.web;

import com.alibaba.fastjson.JSONObject;
import com.coincalf.chan.feign.MessagingServiceClient;
import com.coincalf.dto.MatchDTO;
import com.coincalf.dto.TxDTO;
import com.coincalf.entity.Market;
import com.coincalf.framework.constants.Constant;
import com.coincalf.framework.http.Response;
import com.coincalf.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description: 撮合成功后更新缓存数据
 * @Author: Chen Long
 * @Date: Created in 2018/5/20 下午4:55
 * @Modified by: Chen Long
 */
@RestController
@RequestMapping("/match")
@Slf4j
public class MatchController {

    @Autowired
    private MarketService marketService;
    @Autowired
    private EntrustOrderService entrustOrderService;
    @Autowired
    private TurnoverOrderService turnoverOrderService;
    @Autowired
    private MessagingServiceClient messagingServiceClient;


    /**
     * 币币交易撮合成功后
     *
     * @return
     */
    @PostMapping("/trade")
    public Response tradeMatch(@RequestBody MatchDTO matchDTO) {
        log.info("撮合后更新缓存：{}", matchDTO.toString());
        Market market = marketService.queryBySymbol(matchDTO.getSymbol());
        // 更新交易对行情
        marketService.TRADE_MARKET_CACHE_INSTANCE().refresh(market.getId());
        // 更新委托队列-默认合并深度
        entrustOrderService.DEPTH_CACHE_INSTANCE().refresh(market.getId());
        // 更新委托队列-合并深度1
        entrustOrderService.MERGE_LOW_DEPTH_CACHE_INSTANCE().refresh(market.getId());
        // 更新委托队列-合并深度2
        entrustOrderService.MERGE_HIGH_DEPTH_CACHE_INSTANCE().refresh(market.getId());
        // 更新成交记录
        turnoverOrderService.DEAL_ORDER_CACHE_INSTANCE().refresh(market.getId());
        this.pushUserTradeEntrustOrder(matchDTO.getBuyUserId(), matchDTO.getSymbol());
        if (!matchDTO.getBuyUserId().equals(matchDTO.getSellUserId())) {
            this.pushUserTradeEntrustOrder(matchDTO.getSellUserId(), matchDTO.getSymbol());
        }
        return Response.ok("ok");
    }

    /**
     * 币币交易撮合成功后
     *
     * @return
     */
    @PostMapping("/forex")
    public Response forexMatch(@RequestBody MatchDTO matchDTO) {
        Market market = marketService.queryBySymbol(matchDTO.getSymbol());
        // 更新交易对行情
        marketService.FOREX_MARKET_CACHE_INSTANCE().refresh(market.getId());
        this.pushUserForexOrder(matchDTO.getBuyUserId());
        if (!matchDTO.getBuyUserId().equals(matchDTO.getSellUserId())) {
            this.pushUserForexOrder(matchDTO.getSellUserId());
        }
        return Response.ok("ok");
    }

    /**
     * 推送用户币币交易委托订单数据
     *
     * @param userId 用户ID
     */
    private void pushUserTradeEntrustOrder(Long userId, String symbole) {
        // 推送用户未成交委托
        JSONObject body = new JSONObject();
        body.put("symbol", symbole);
        // 通知用户拉取未成交委托
        messagingServiceClient.convertAndSendToUser(Constant.CH_ORDER_PENDING, String.valueOf(userId), body.toJSONString());
        // 通知用户拉取历史委托
        messagingServiceClient.convertAndSendToUser(Constant.CH_ORDER_FINISHED, String.valueOf(userId), body.toJSONString());
    }

    /**
     * 推送用户创新交易订单数据（持仓明细、持仓汇总、今日平仓、今日委托、今日成交）
     *
     * @param userId 用户ID
     */
    private void pushUserForexOrder(Long userId) {
        // 通知用户拉取持仓明细
        messagingServiceClient.convertAndSendToUser(Constant.CH_POSITION_DETAILS_UPDATE, String.valueOf(userId), "ok");
        // 通知用户拉取持仓汇总
        messagingServiceClient.convertAndSendToUser(Constant.CH_POSITION_SUMMARY_UPDATE, String.valueOf(userId), "ok");
        // 通知用户拉取今日平仓
        messagingServiceClient.convertAndSendToUser(Constant.CH_CLOSEPOSITION_ORDERS_UPDATE, String.valueOf(userId), "ok");
        // 通知用户拉取今日委托
        messagingServiceClient.convertAndSendToUser(Constant.CH_ENTRUST_ORDERS_UPDATE, String.valueOf(userId), "ok");
        // 通知用户拉取今日成交
        messagingServiceClient.convertAndSendToUser(Constant.CH_TURNOVER_ORDERS_UPDATE, String.valueOf(userId), "ok");
    }

    /**
     * 币币交易撮合后修改资金账户
     *
     * @param txDTO 用户ID
     */
    Response match(@RequestBody TxDTO txDTO) {
        turnoverOrderService.match(txDTO);
        return Response.ok();
    }

}
